package com.data.web.config;

import com.data.biz.domain.AccData;
import com.data.biz.domain.DipData;
import com.data.biz.service.IBizAccService;
import com.data.biz.service.IBizDipService;
import com.data.web.handlerTcpData.DataService;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;


@Slf4j
@Service
@ChannelHandler.Sharable
public class NettyServerHandler extends ChannelInboundHandlerAdapter {

    @Autowired
    private IBizDipService dipService;

    @Autowired
    private IBizAccService accService;


    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException {
        // 处理客户端发送的数据
        ByteBuf byteBuf = (ByteBuf) msg;
        byte[] originData = new byte[byteBuf.readableBytes()];
        byteBuf.readBytes(originData);
//        originData = new byte[]{79, 70, 70, 73, 67, 69, 95, 73, 78, 67, 95, 67, 72, 57, 51, 52, 52, 85, 83, 66, 49, 45, 45, 45, -65, -125, 2, 125, -65, -126, 96, -92, -65, -125, -65, 54, 63, -125, 2, -115, 66, -80, -29, 118, 66, -80, -25, 8, 66, -80, -32, 75, 66, -80, -29, 118, 63, -108, 116, 31, 63, -107, 87, 43, 63, -109, -81, 4, 63, -108, 116, 46, 65, -91, 31, -74, 65, -91, 48, 57, 65, -91, 8, 98, 32, 36, 7, 0, 1, 0, 0, 0, 83, 57, -35, 103, 13, 10};
        byte[] delimiter = {45, 45, 45};
        byte[] head = getBytelistHead(originData, delimiter);
        String headStr = new String(head, "utf-8");
        String deviceId = Arrays.asList(headStr.split("_")).get(0);
        if(headStr.contains("INC")){
            List<byte[]> bytelist = getBytelistData(originData, delimiter);
            DipData data = new DipData();
            data.setxMean(getFloat(bytelist.get(0)).setScale(3, RoundingMode.HALF_UP));
            data.setxMax(getFloat(bytelist.get(1)).setScale(3, RoundingMode.HALF_UP));
            data.setxMin(getFloat(bytelist.get(2)).setScale(3, RoundingMode.HALF_UP));
            data.setxEff(getFloat(bytelist.get(3)).setScale(3, RoundingMode.HALF_UP));

            data.setyMean(getFloat(bytelist.get(4)).setScale(3, RoundingMode.HALF_UP));
            data.setyMax(getFloat(bytelist.get(5)).setScale(3, RoundingMode.HALF_UP));
            data.setyMin(getFloat(bytelist.get(6)).setScale(3, RoundingMode.HALF_UP));
            data.setyEff(getFloat(bytelist.get(7)).setScale(3, RoundingMode.HALF_UP));

            data.setzMean(getFloat(bytelist.get(8)).setScale(3, RoundingMode.HALF_UP));
            data.setzMax(getFloat(bytelist.get(9)).setScale(3, RoundingMode.HALF_UP));
            data.setzMin(getFloat(bytelist.get(10)).setScale(3, RoundingMode.HALF_UP));
            data.setzEff(getFloat(bytelist.get(11)).setScale(3, RoundingMode.HALF_UP));
            data.settMean(getFloat(bytelist.get(12)).setScale(3, RoundingMode.HALF_UP));
            data.setRawId(getInt(bytelist.get(15)).longValue());
            data.setRawNo(getInt(bytelist.get(16)).intValue());
            data.setCreateTime(new Date(getInt(bytelist.get(17)).longValue() * 1000L));
            data.setIsDelete((short)0);
            data.setId(getInt(bytelist.get(15)).longValue());
            dipService.doSaveSingleDipData(data,deviceId);
        }else if(headStr.contains("ACC")){
            List<byte[]> bytelist = getBytelistData(originData, delimiter);
            AccData data = new AccData();
            data.setxMean(getFloat(bytelist.get(0)).setScale(3, RoundingMode.HALF_UP));
            data.setxMax(getFloat(bytelist.get(1)).setScale(3, RoundingMode.HALF_UP));
            data.setxMin(getFloat(bytelist.get(2)).setScale(3, RoundingMode.HALF_UP));
            data.setxEff(getFloat(bytelist.get(3)).setScale(3, RoundingMode.HALF_UP));

            data.setyMean(getFloat(bytelist.get(4)).setScale(3, RoundingMode.HALF_UP));
            data.setyMax(getFloat(bytelist.get(5)).setScale(3, RoundingMode.HALF_UP));
            data.setyMin(getFloat(bytelist.get(6)).setScale(3, RoundingMode.HALF_UP));
            data.setyEff(getFloat(bytelist.get(7)).setScale(3, RoundingMode.HALF_UP));

            data.setzMean(getFloat(bytelist.get(8)).setScale(3, RoundingMode.HALF_UP));
            data.setzMax(getFloat(bytelist.get(9)).setScale(3, RoundingMode.HALF_UP));
            data.setzMin(getFloat(bytelist.get(10)).setScale(3, RoundingMode.HALF_UP));
            data.setzEff(getFloat(bytelist.get(11)).setScale(3, RoundingMode.HALF_UP));
            data.settMean(getFloat(bytelist.get(12)).setScale(3, RoundingMode.HALF_UP));

            data.setxFre1(getFloat(bytelist.get(15)).setScale(3, RoundingMode.HALF_UP));
            data.setxFre2(getFloat(bytelist.get(16)).setScale(3, RoundingMode.HALF_UP));
            data.setxFre3(getFloat(bytelist.get(17)).setScale(3, RoundingMode.HALF_UP));
            data.setxPow1(getFloat(bytelist.get(18)).setScale(3, RoundingMode.HALF_UP));
            data.setxPow2(getFloat(bytelist.get(19)).setScale(3, RoundingMode.HALF_UP));
            data.setxPow3(getFloat(bytelist.get(20)).setScale(3, RoundingMode.HALF_UP));

            data.setyFre1(getFloat(bytelist.get(21)).setScale(3, RoundingMode.HALF_UP));
            data.setyFre2(getFloat(bytelist.get(22)).setScale(3, RoundingMode.HALF_UP));
            data.setyFre3(getFloat(bytelist.get(23)).setScale(3, RoundingMode.HALF_UP));
            data.setyPow1(getFloat(bytelist.get(24)).setScale(3, RoundingMode.HALF_UP));
            data.setyPow2(getFloat(bytelist.get(25)).setScale(3, RoundingMode.HALF_UP));
            data.setyPow3(getFloat(bytelist.get(26)).setScale(3, RoundingMode.HALF_UP));

            data.setzFre1(getFloat(bytelist.get(27)).setScale(3, RoundingMode.HALF_UP));
            data.setzFre2(getFloat(bytelist.get(28)).setScale(3, RoundingMode.HALF_UP));
            data.setzFre3(getFloat(bytelist.get(29)).setScale(3, RoundingMode.HALF_UP));
            data.setzPow1(getFloat(bytelist.get(30)).setScale(3, RoundingMode.HALF_UP));
            data.setzPow2(getFloat(bytelist.get(31)).setScale(3, RoundingMode.HALF_UP));
            data.setzPow3(getFloat(bytelist.get(32)).setScale(3, RoundingMode.HALF_UP));
            data.setRawId(getInt(bytelist.get(33)).longValue());
            data.setRawNo(getInt(bytelist.get(34)).intValue());
            data.setCreateTime(new Date(getInt(bytelist.get(35)).longValue() * 1000L));
            data.setIsDelete((short)0);
            data.setId(getInt(bytelist.get(33)).longValue());

            accService.doSaveSingleAccData(data,deviceId);
        }else {
            log.error("收到未知数据");
        }


    }

    private static List<byte[]> getBytelistData(byte[] originData, byte[] delimiter) {
        List<byte[]> result = splitByteArray(originData, delimiter);
        return splitByteArray(result.get(1), 4);
    }

    private static byte[] getBytelistHead(byte[] originData, byte[] delimiter) {
        List<byte[]> result = splitByteArray(originData, delimiter);
        return result.get(0);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // 处理异常
        cause.printStackTrace();
        ctx.close();
    }

    public BigDecimal getInt( byte[] bytes){
        ByteBuffer buffer = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN);
        int value =buffer.getInt();
        return new BigDecimal(value);
    }

    public BigDecimal getFloat( byte[] bytes){
        ByteBuffer buffer = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN);
        float value =buffer.getFloat();
        return new BigDecimal(value);
    }


    public static List<byte[]> splitByteArray(byte[] byteArray, int chunkSize) {
        List<byte[]> result = new ArrayList<>();

        // 遍历字节数组
        for (int i = 0; i < byteArray.length; i += chunkSize) {
            // 计算当前子数组的长度
            int length = Math.min(chunkSize, byteArray.length - i);
            // 创建子数组
            byte[] chunk = new byte[length];
            // 复制数据
            System.arraycopy(byteArray, i, chunk, 0, length);
            // 添加到结果列表
            result.add(chunk);
        }

        return result;
    }

    public static List<byte[]> splitByteArray(byte[] byteArray, byte[] delimiter) {
        List<byte[]> result = new ArrayList<>();
        int start = 0; // 分割起始位置
        int delimiterLength = delimiter.length;

        for (int i = 0; i <= byteArray.length - delimiterLength; i++) {
            // 检查是否匹配分隔符
            boolean match = true;
            for (int j = 0; j < delimiterLength; j++) {
                if (byteArray[i + j] != delimiter[j]) {
                    match = false;
                    break;
                }
            }

            if (match) {
                // 找到分隔符，截取前面的部分
                byte[] part = new byte[i - start];
                System.arraycopy(byteArray, start, part, 0, i - start);
                result.add(part);
                start = i + delimiterLength; // 更新起始位置
                i += delimiterLength - 1; // 跳过分隔符
            }
        }

        // 添加最后一部分
        if (start < byteArray.length) {
            byte[] part = new byte[byteArray.length - start];
            System.arraycopy(byteArray, start, part, 0, byteArray.length - start);
            result.add(part);
        }

        return result;
    }


    public static byte[] mergeByteArrays(List<byte[]> byteArrayList) {
        // 计算总长度
        int totalLength = 0;
        for (byte[] array : byteArrayList) {
            totalLength += array.length;
        }

        // 创建目标字节数组
        byte[] mergedArray = new byte[totalLength];

        // 复制数据
        int offset = 0;
        for (byte[] array : byteArrayList) {
            System.arraycopy(array, 0, mergedArray, offset, array.length);
            offset += array.length;
        }

        return mergedArray;
    }
}
